﻿using BugSplattr.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;

namespace BugSplattr.Controllers
{
    public class BugSplatController : Controller
    {
        private BugSplatService _service;                       // Sets the singleton for accessing the Service instance
        public BugSplatController()                             // Instantiates the BugSplat Controller's singleton 
        {
            _service = BugSplatService.Instance;                // Assigns the Instance callout to _service (the singleton)
        }
        public ActionResult Index()                             // Click on "See all bugs and tasks" on the navbar and voila, you're here
        {
            BugSplatIndexVM AllBugs = new BugSplatIndexVM();    // Instantiate new BugSplatIndexVM (erases previous stuff and prepares for new stuff)
            AllBugs.Greeting = "All bugs and Tasks";            // Set greeting for h2 in html
            AllBugs.WorkItems = _service.GetTodos();            // grabs the list of bugs/tasks and puts it in the variable
            return View(AllBugs);                               // Dumps the greeting and list out to the view page, where the @razor stuff takes care of it
        }
        public ActionResult Bugs()                              // Click on "See only the bugs" on the navbar and voila, you're here
        {
            BugSplatIndexVM JustBugs = new BugSplatIndexVM();   // Instantiate new BugSplatIndexVM (read above you lazy cunt)
            List<WorkItem> listOfBugs = _service.GetTodos();    // Grabs the existing list from the service
            var bugList = listOfBugs.Where(b => b.GetType().Name == "Bug").OrderBy(b => b.Id).ToList();     // Filters that list to show only objects of Bug class and sorts by ID (1 -> 10, not 10 -> 1)
            JustBugs.Bugs = bugList.Cast<Bug>().ToList();       // Turns the list in to a Bug list (not WorkItem anymore) so that it can be set to the Bug class list in BugSplatIndexVM
            return View(JustBugs);                              // Dumps the list out to the view page, where the @razor stuff takes care of it
        }
        public ActionResult Tasks()                             // Click on "See only the tasks" on the navbar and voila, you're here
        {
            BugSplatIndexVM JustTasks = new BugSplatIndexVM();  // Instantiate new BugSplatIndexVM (read further above you lazy cunt)
            List<WorkItem> listOfTasks = _service.GetTodos();   // Grabs the existing list from the service
            var taskList = listOfTasks.Where(t => t.GetType().Name == "TaskToDo").OrderBy(t => t.Id).ToList();  // Filters that list to show only objects of TaskToDo class and sorts by ID (1 -> 10, not 10 -> 1)
            JustTasks.Tasks = taskList.Cast<TaskToDo>().ToList();   // Turns the list in to a TaskToDo list (not WorkItem anymroe) so that it can be set to the Tasks class list in BugSplatIndexVM
            return View(JustTasks);                             // Dumps the list out to the view page, where the @razor stuff takes care of it
        }

        [HttpGet]                                               // Because there are two different action results for Create, the first one is for the Get (where they fill in fields)
        public ActionResult Create()                            // Click on "Create new bug" on the navbar and voila, you're here
        {
            BugSplatCreateBug cvm = new BugSplatCreateBug();    // Instantiate new BugSplatCreateBug view model (you know what it's doing)
            cvm.Greeting = "Add a bug";                         // Sets a greeting to be coughed out on the browser screen
            return View(cvm);                                   // Dumps the greeting out to the view page
        }
        [HttpPost]                                              // Second action result is what happens when you click on submit
        public ActionResult Create(BugSplatCreateBug cVm)       // This is just the follow through on clicking submit.  Don't worry about it, just know that there needs to be two of them because of the get/post purpose of the action result
        {
            int myResults = _service.CreateBug(cVm.Title, DateTime.Now, cVm.Priority, cVm.StepsToReproduce);    // Sending the field information off to the service to create a bug, passing along all the necessary paramaters to create it
            return RedirectToAction("Index");                   // Returns the viewer back to the View All Bugs and Tasks page
        }
        [HttpGet]                                               // Because there are two different action results for Create, the first one is for the Get (where they fill in fields)
        public ActionResult CreateTask()                        // Click on "Create new task" on the navbar and voila, you're here
        {
            BugSplatCreateTask cvm = new BugSplatCreateTask();  // Instantiate new BugSplatCreateTask view model (you know what it's doing)
            cvm.Greeting = "Add a task";                        // Sets a greeting to be coughed out on the browser screen
            return View(cvm);                                   // Dumps the greeting out to the view page
        }
        [HttpPost]                                              // Second action result is what happens when you click on submit
        public ActionResult CreateTask(BugSplatCreateTask cVm)  // This is just the follow through on clicking submit.  Don't worry about it, just know that there needs to be two of them because of the get/post purpose of the action result 
        {
            int myResults = _service.CreateTask(cVm.Title, DateTime.Now, cVm.Priority, cVm.Description);    // Sending the field information off to the service to create a task, passing along all the necessary paramaters to create it
            return RedirectToAction("Index");                   // Returns the viewer back to the View All Bugs and Tasks page
        }

        [HttpGet]                                               // Because there are two different action results for Create, the first one is for the Get (where they fill in fields)
        public ActionResult Update(int id)                      // Click on "Edit" button on a bug item in a list and voila, you're here
        {
            BugSplatUpdateVM uVm = new BugSplatUpdateVM();      // Instantiate new BugSplatUpdateVM view model (you know what it's doing)
            Bug objToUpdate = (Bug)_service.BugToUpdate(id);    // Sets up a Bug object, with the properties of the same object in the list with the same id. Necessary because you will be returning a bug, and also because you want the fields to be able to produce a StepsToReproduce (part of the Bug class)
            uVm.Title = objToUpdate.Title;                      // Gives the Title property of the VM the same value as the object being edited, so you can fill the Title field with the existing title value
            uVm.StepsToReproduce = objToUpdate.StepsToReproduce; // Same as above, but for the StepsToReproduce property
            return View(uVm);                                   // Dumps the information to the view page to fill the fields using @razor stuff
        }
        [HttpPost]                                              // Second action result is what happens when you click on submit
        public ActionResult Update(BugSplatUpdateVM uVm)        // This is just the follow through on clicking submit.  Don't worry about it, just know that there needs to be two of them because of the get/post purpose of the action result
        {
            Bug upVm = new Bug(uVm.Id, uVm.Title, uVm.DateCreated, uVm.Priority, uVm.StepsToReproduce); // Creates a new bug with the information handed down from the fields by the user
            _service.UpdateBug(upVm.Id, upVm.Title, upVm.StepsToReproduce);                             // Sends the new bug's information to the service to replace existing object with new object properties
            return RedirectToAction("Index");                   // Returns the viewer back to the View All Bugs and Tasks page
        }
        [HttpGet]                                               // Because there are two different action results for Create, the first one is for the Get (where they fill in fields)
        public ActionResult UpdateTask(int id)                  // Click on "Edit" button on a TaskToDo item in a list and voila, you're here
        {
            BugSplatUpdateVM utVm = new BugSplatUpdateVM();     // Instantiate new BugSplatUpdateVM view model (you know what it's doing) 
            TaskToDo objToUpdate = (TaskToDo)_service.TaskToUpdate(id); // Sets up a TaskToDo object, with the properties of the same object in the list with the same id. Necessary because you will be returning a TaskToDo, and also because you want the fields to be able to produce a Description (part of the TaskToDo class) 
            utVm.Title = objToUpdate.Title;                     // Gives the Title property of the VM the same value as the object being edited, so you can fill the Title field with the existing title value 
            utVm.Description = objToUpdate.Description;         // Same as above, but for the Description property
            return View(utVm);                                  // Dumps the information to the view page to fill the fields using @razor stuff 
        }
        [HttpPost]                                              // Second action result is what happens when you click on submit
        public ActionResult UpdateTask(BugSplatUpdateVM utVm)   // This is just the follow through on clicking submit.  Don't worry about it, just know that there needs to be two of them because of the get/post purpose of the action result 
        {
            TaskToDo upVm = new TaskToDo(utVm.Id, utVm.Title, utVm.DateCreated, utVm.Priority, utVm.Description);   // Creates a new TaskToDo with the information handed down from the fields by the user 
            _service.UpdateTask(upVm.Id, upVm.Title, upVm.Description); // Sends the new task's information to the service to replace existing object with new object properties 
            return RedirectToAction("Index");                   // Returns the viewer back to the View All Bugs and Tasks page 
        }
        public ActionResult Delete(int id)                      // If you click delete, this happens.  It deletes the thing from the list
        {
            _service.DeleteBug(id);                             // Sends the id of the object to be deleted to the service, which will find it and delete it from the list
            return RedirectToAction("Index");                   // Returns the viewer back to the View All Bugs and Tasks page
        }
    }
}